import React, { useState, useEffect } from 'react'
import { render } from 'react-dom'

import App from './App'

import { CounterProvider } from './countStore'
import CountApp from './countApp'

import HocApp from './HocApp'

import CarApp from './carApp'
import store from './store'
// 使用react-redux连接的方式
import {Provider} from 'react-redux'

import ImmutableApp from './ImmutableApp'
import imStore from './immutable-redux/store'

// import {BrowserRouter as Router, Route} from 'react-router-dom'   // history模式
import {HashRouter as Router, Route} from 'react-router-dom'
import RouteApp from './routeApp'

const Counter = () => {

    let [count, setCount] = useState(0)  
    useEffect(() => {
        console.log('渲染了')
    })
    return (
        <div>
            <p>当前数量是{count}</p>
            <button onClick={() => {setCount(count - 1)}}>-</button>
            <span>{count}</span>
            <button onClick={() => {setCount(count + 1)}}>+</button>
        </div>
    )
}


render(
    // 只能一个根标签，所以用一个标签包裹
    <>
        <App />
        <hr />
        <Counter />
        <hr />
        <CounterProvider>
            <CountApp />
        </CounterProvider>
        <hr />
        <HocApp />
        {/* 手动传递的方法 */}
        {/* <CarApp store={store} /> */}
        {/* react-redux是用context的方法，跨组件传递， 在需要使用store的组件内 导入 connect 进行连接 */}
        <Provider store={store}>
            <CarApp />
        </Provider>
        {/* react-router */}
        {/* 路由包裹 */}
        <Router>
            <Route component={RouteApp}></Route>
        </Router>
        {/* redux-immutable */}
        <Provider store={imStore}>
            <ImmutableApp />
        </Provider>
    </>,
    document.querySelector('#root')
)


/*
// 拆分组件模块
// // createContext是一个react提供的用于跨组件传值的方法
// import React, { Component, createContext } from 'react'
// import { render } from 'react-dom'

// // createContext这个方法的结果是一个对象，里面有两个组件：Provider和Consumer
// // Provider用于提供状态，Consumer用于接收状态
// const {
//     Provider,
//     Consumer: CountConsumer      // 结构出来重新赋值给一个CounterConsumer的组件  
// } = createContext()

// // 封装一个基本的Provider,因为直接使用Provider,不方便管理状态
// class CounterProvider extends Component {
//     constructor() {
//         super()
//         // 这里的状态就是共享的，任何CounterProvider的后代组件都可以通过CounterConsumer来接收这个值
//         this.state = {
//             count: 100
//         }
//     }
//     // 这里的方法也会通过Provider传递下去
//     incrementCount = () => {
//         this.setState({
//             count: this.state.count + 1
//         })
//     }
//     decrementCount = () => {
//         this.setState({
//             count: this.state.count - 1
//         })
//     }

//     render () {
//         return (
//             // 使用Provider这个组件，它必须要有一个value值，这个value里可以传递任何数据，一般还是传递一个对象
//             <Provider value={{
//                 count: this.state.count,
//                 onIncrementCount: this.incrementCount,
//                 onDecrementCount: this.decrementCount
//             }}>
//                 {this.props.children}
//             </Provider>
//         )
//     }
// }

// // 定义一个counter组件
// class Counter extends Component {
//     render() {
//         return (
//             // 使用CounterConsumer来接收count
//             <CountConsumer>
//                 {
//                     // 注意：Consumer的children必须是一个方法，这个方法有一个参数，这个参数就是Provider的value 
//                     (arg) => {
//                         return <span>{arg.count}</span>
//                     }
//                 }
//             </CountConsumer>
//         )
//     }
// }

// class CountBtn extends Component {
//     render() {
//         return (
//             <CountConsumer>
//                 {
//                     (arg) => {
//                         const handler = this.props.type === 'increment' ? arg.onIncrementCount : arg.onDecrementCount
//                         return <button onClick={handler}>{this.props.children}</button>
//                     }
//                 }
//             </CountConsumer>
//         )
//     }
// }

// class App extends Component {
//     render () {
//         return (
//             <>
//                 <CountBtn type="decrement">-</CountBtn>
//                 <Counter></Counter>
//                 <CountBtn type="increment">+</CountBtn>
//             </>
//         )
//     }
// }

// render(
//     <CounterProvider>
//         <App />
//     </CounterProvider>,
//     document.querySelector('#root')
// )
*/


// // React Hooks是16.8新增的一个特性，可以在不编写class的情况下（写函数式组件时）使用state以及其他的react特性
// // Hooks: 常用的两个api: useState和useEffect   需要先引入
// import React, { useState, useEffect } from 'react'
// import { render } from 'react-dom'

// const Counter = () => {
//     // useState是一个方法，这个方法的参数就是默认值，结果是一个数组,数组第一个就是state，第二个相当于setState,解构出来
//     let [count, setCount] = useState(0)         // 括号里面是一个初始值
//     // 可以写多个
//     // const { title, setTitle } = useState('初始值')        
//     // const { age, setAge } = useState(10)   
//     // useEffect的参数是一个回调，不管是组件挂载还是更新，都会触发这个回调方法，类似于componentDidMount和componentDidUpdate的结合
//     // 可以看做事件监听
//     useEffect(() => {
//         console.log('数值变化了')
//         document.title = `当前数量是${count}`
//     })
//     return (
//         <div>
//             <p>当前数量是{count}</p>
//             {/* 这里setCount就是useState生成的方法（第二个）。与setState不同的地方在于这个方法的参数是一个新值即可 */}
//             <button onClick={() => {setCount(count - 1)}}>-</button>
//             {/* 这里count就是useState创建的值（第一个） */}
//             <span>{count}</span>
//             <button onClick={() => {setCount(count + 1)}}>+</button>
//         </div>
//     )
// }


// render(
//     <Counter />,
//     document.querySelector('#root')
// )




// import React from 'react'
// import { render } from 'react-dom'

// import App from './App'

// render(
//     <App />,
//     document.querySelector('#root')
// )








// import React, {Component} from 'react'
// import {render} from 'react-dom'
// import classNames from 'classnames'

// import './index.css'

// class App extends Component {
//     render () {
//         const style= {color:'red'}
//         // 样式
//         return (
//             <div>
//                 <h1 style={{color:'red'}}>
//                     元素中的样式
//                 </h1>
//                 <ol>
//                     <li style={style}>
//                         使用style内联创建
//                     </li>
//                     <li className="text-red text-size">使用class方式，但在react里面要写成className,再创建一个css文件，引入</li>
//                     <li className={classNames('a',{'b':true,'c':false})}>要动态添加不同的className就可以使用第三方的包classnames,比如这个标签上只有a和b，没有c</li>
//                 </ol>
//             </div>
//         )
//     }
// }

// render(
//     <App />,
//     document.querySelector("#root")
// )





// import React from 'react'
// import ReactDom from 'react-dom'

/*jsx原理*/
// class App extends React.Component{ 
//     render(){
//         return (
//             React.creatElement(
//                 'div',
//                 {
//                     className: 'app',
//                     id: 'appRoot'
//                 },
//                 React.creatElement(
//                     'h1',
//                     {
//                         className: 'title'
//                     },
//                     'jsx原理'
//                 ),
//                 React.creatElement(
//                     'p',
//                     null,
//                     '虚拟dom创建'
//                 )
//             )
//         )
//     }
// }

// 定义组件的第二种方式，使用类 ，可以使用什么周期
// class App extends React.Component{        //创建类去继承react的组件
//     render(){
//         console.log(this.props)
//         return (
//             <div>
//                 <h1>类组件</h1>
//                 <p>{this.props.title}</p>
//             </div>
//         )
//     }
// }
// new之后调用render方法才会去渲染
// 类组件原理
// const app = new App({
//     desc:"类组件是继承React.Component"
// }).render()

// render是ReactDom提供的一个方法，这个方法通常只使用一次
// ReactDom.render(
//     // <h1>类组件</h1>,
//     <App title="类组件是继承React.Component"/>,
//     // app,   // 原理 render的
//     document.querySelector('#root')
// )

// // react16版本以前会用这种方式  创建一个class
// React.createClass({
//     reader() {
//         return <h1>xxx</h1>
//     }
// })





// 这种方式可以理解为创建了一个简单的react元素
// const app = <h1>welcome react!!!</h1>
// const createApp = ()=>{
//     return <h1>welcome react!!!</h1>
// } 
// const createApp = (props)=>{
//     return <div>
//         <h1>welcome {props.title}</h1>
//         <p>优秀的{props.title}</p>
//     </div>
// } 
// const createApp = (props)=>{
//     return (
//         <div>
//             {/* 只要在jsx里写js代码，就加一层花括号，注释也是js，所以这里有一层花括号 */}
//             <h1>welcome {props.title}</h1>
//             <p>优秀的{props.title}</p>
//         </div>
//     )
// } 
// 函数式组件的原理，函数执行一下
// const app = createApp({
//     title:'react111'
// })
// ReactDom.render(
//     app,
//     document.querySelector('#root')
// )

// // 创建组件的第一种方式，使用箭头函数，但这个名字要大写字母开始
// 函数式组件
// const App = (props)=>{
//     return (
//         <div>
//             {/* 只要在jsx里写js代码，就加一层花括号，注释也是js，所以这里有一层花括号 */}
//             <h1>welcome {props.title}</h1>
//             <p>优秀的{props.title}</p>
//         </div>
//     )
// } 

// ReactDom.render(
//     <App title="65465" />,
//     document.querySelector('#root')
// )